#include "zelWindowGL3.h"
#include "utils/cuUtils.h"
#include "z3d/zel_engine.h"
#include "../internal/engine_constants.h"



namespace z3d{
	zelWindowGL3::zelWindowGL3(void) 
                :_log(NULL)
                ,_isOpen(false)
                ,_mesh("sample")
	{
            
	}


	zelWindowGL3::~zelWindowGL3(void)
	{

	}
        
        bool zelWindowGL3::open(const uint32_t& width, const uint32_t& height, const uint32_t& bpp, const bool fullscreen, const std::string& title) {
            _width = width;
            _height = height;
            _bpp = bpp;
            _fullscreen = fullscreen;
            _title = title;
#ifdef _DEBUG
            _title += " - DEBUG";
#endif            
            int mode = _fullscreen?GLFW_FULLSCREEN:GLFW_WINDOW;
            _log->DEBUG_MSG(Z3D_APPENDER, "Opening window with %dx%d %d in %s mode", _width, _height, _bpp, _fullscreen?"fullscreen":"windowed");
            if(!glfwOpenWindow(_width, _height, 8, 8, 8, 8, 32, 32, mode)) {
                THROW_AND_LOG(Z3D_APPENDER, z3d::core::Z3DRuntimeException, "glfwOpenWindow failed. Can your hardware handle OpenGL 3.2?");
			}
            _log->DEBUG_MSG(Z3D_APPENDER, "Initializing glew");
			glewExperimental = GL_TRUE;
			if(glewInit() != GLEW_OK) {
				THROW_AND_LOG(Z3D_APPENDER, z3d::core::Z3DRuntimeException, "glew init failed");
			}
			_log->DEBUG_MSG(Z3D_APPENDER, "Requesting opengl 3.2 API to glew");
			if(!GLEW_VERSION_3_2) {
				THROW_AND_LOG(Z3D_APPENDER, z3d::core::Z3DRuntimeException, "OpengGL 3.2 API is not available");
			}
            _isOpen = true;
            glfwSetWindowTitle(_title.c_str());
            return true;
        }
        
        bool zelWindowGL3::isOpen() {
            return _isOpen;
        }
        
        bool zelWindowGL3::render() {
            // clear everything
            glClearColor(0.2f, 0.2f, 0, 1); // black
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glfwSwapBuffers();
            return true;
        }
        
        bool zelWindowGL3::init() {
            _log = &glog::CGlobalLog::getSingleton();
            _log->DEBUG_MSG(Z3D_APPENDER, "Initializing GLFW...");
            // inicializar glfw
            if(!glfwInit()) {
                THROW_AND_LOG(Z3D_APPENDER, z3d::core::Z3DRuntimeException, "Cannot init GLFW!!!");
            }
            glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
            glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
            glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2);
            glfwOpenWindowHint(GLFW_WINDOW_NO_RESIZE, GL_TRUE);
            
            return true;
        }
        
        bool zelWindowGL3::close() {
            _log->DEBUG_MSG(Z3D_APPENDER, "Closing window and terminating glfw system");
            glfwCloseWindow();
            glfwTerminate();
            return true;
        }
}